
var express = require('express');
var router = express.Router();
const {Course,Category,User,Chapter} = require('../../models')
const {Op} = require('sequelize')
console.log(Course);
const {NotFoundError,success,failure} = require('../../utils/response');


/* GET home page. */
router.get('/', async function(req, res, next) {
    try {
        const query = req.query
        // 防止页码不是数字或不是正数或用户没有输入
        const currentPage = Math.abs(Number(query.currentPage)) || 1
        const pageSize = Math.abs(Number(query.pageSize)) || 10
        const offset = (currentPage-1)*pageSize
        const condition = {//定义一个查询条件，这里是按照id字段倒序查询 使用时放在查询语句中即可
            order:[['id','DESC']],
            //实现数据分页时，数据库语句需要下面这两个参数
            limit:pageSize,//此参数为查询几条数据
            offset:offset,//此参数为从第几条数据开始查询
            // 配置关联模型
            // 前端在拿到接口数据的时候可能不知道categoryid和userid对应的具体是什么分类和用户，
            // 但通过关联模型就可以在返回数据中自己添加上categoryid和userid对应的数据表的内容,需要在courses的模型中配置
            // exclude为查询结果 排除 这两个字段
            attributes:{exclude:['CategoryId','UserId']},
            include:[
                {
                    model:Category,
                    as:'category',
                    attributes:['id','name']
                },
                {
                    model:User,
                    as:'user',
                    attributes:['id','username','avatar']
                }
            ]
        }

        // 精确查询
        if(query.categoryId){
            condition.where = {
                categoryId:{
                    [Op.eq]: query.categoryId
                }
            }
        }

        if(query.userId){
            condition.where = {
                userId:{
                    [Op.eq]: query.userId
                }
            }
        }
        //模糊查询
        if(query.name){
            condition.where = {
                name:{
                    [Op.like]: `%${query.name}%`
                }
            }
        }

        if(query.recommended){
            condition.where = {
                recommended:{
                    // 请求中的数据是字符串形式的，所以这里要判断数据
                    [Op.eq]: query.recommended === 'true'
                }
            }
        }

        if(query.introductory){
            condition.where = {
                introductory:{
                    // 请求中的数据是字符串形式的，所以这里要判断数据
                    [Op.eq]: query.introductory === 'true'
                }
            }
        }


        // 实现数据分页
        // 此方法返回的count为查询出来的数据总数，rows是最终查询出来的数据
        const {count,rows} = await Course.findAndCountAll(condition) //查询articles表中的所有数据，是异步操作
        res.json({
            status:true,
            message:'查询课程列表成功',
            data:{
                courses:rows,
                pagination:{
                    total:count,
                    currentPage,
                    pageSize,
                }
            }
        });
    } catch (error) {
        failure(res,error)
    }
    
});


// 根据id查找课程
router.get('/:id', async function(req, res, next) {
    try {
        const course = await getCourse(req) 
        success(res,'查询课程列表成功',course)
    } catch (error) {
        failure(res,error)
    }
    
});


// 新增课程
router.post('/',async function(req,res){
    try {
        // 白名单过滤 只将req.body中用户传入的参数的某一些写入数据库,
        // 而不是将整个req.body都写入，防止用户对数据库非法操作
        // 在此项目中，id字段由数据库自行自增，不需要认为写入，但不使用白名单过滤的话就可以通过如apifox工具将id自行写入，这样会导致id自增有误
        const body = filterBody(req)
        body.userId = req.user.id
        const course = await Course.create(body)
        // 状态码201代表请求成功并创建了新资源
        success(res,'创建课程成功',{course},201)
    } catch (error) {
        failure(res,error)
    }
    
})



// 删除课程
router.delete('/:id',async function(req,res){
    try {
        const course = await getCourse(req) 
        const count = await Chapter.count({where:{courseId:req.params.id}})
        if(count > 0){
            throw new Error('当前课程不为空，无法删除')
        }
        await course.destroy()
        success(res,'删除课程成功')
    } catch (error) {
        failure(res,error)
    }
    
})

// 更新课程
router.put('/:id',async function(req,res){
    try {
        const course = await getCourse(req)
        const body = filterBody(req)
        await course.update(body)
        success(res,'更新课程成功',{course})
    } catch (error) {
        failure(res,error)
    }
    
})


function filterBody(req){
    return {
        categoryId:req.body.categoryId,
        //userId:req.body.userId, 用户id应该是谁登录就是谁的id，而不是用户自己输入,登录的用户中间件中存储在req.user中
        name:req.body.name,
        image:req.body.image,
        recommended:req.body.recommended,
        introductory:req.body.introductory,
        content:req.body.content
    }
}

// 公共的查询方法，可以将未查询到信息的错误抛出
async function getCourse(req){
    const {id} = req.params
    const condition = {
        attributes:{exclude:['CategoryId','UserId']},
        include:[
            {
                model:Category,
                as:'category',
                attributes:['id','name']
            },
            {
                model:User,
                as:'user',
                attributes:['id','username','avatar']
            }
        ]
    }
    const course = await Course.findByPk(id,condition)
    if(!course){
        throw new NotFoundError(`ID:${id}的课程未找到`)
    }
    return course
}


module.exports = router;
